/*
 * protocol_code.h
 *
 *  Created on: Feb 13, 2010
 *      Author: Spartans-UMBC
 */

#include "protocol_code.h"



void resetBus()
{
         enablePins();
        gpio_enable_gpio_pin(NRFD);
        gpio_enable_gpio_pin(EOI);
        gpio_enable_gpio_pin(NDAC);
        gpio_enable_gpio_pin(DAV);
        gpio_enable_gpio_pin(ATN);

        //SetTalk
        //SetControlLines("01000011");        //DDRComm
        //SetControlLines("01110011");        //DDRTALK
        gpio_enable_pin_open_drain(SRQ);
        gpio_enable_pin_open_drain(NRFD);
        gpio_enable_pin_open_drain(NDAC);
        gpio_clr_gpio_pin(REN);
        gpio_clr_gpio_pin(ATN);
        gpio_set_gpio_pin(DAV);
        gpio_set_gpio_pin(EOI);


        //delay at least 100ms for IFC
        //delay_ms1(1);

        gpio_set_gpio_pin(IFC);

        //ADDED
       gpio_set_gpio_pin(TE);
        //gpio_clr_gpio_pin(DC);

}

char * itoa(int value, char *string, int radix)
{
        char tmp[33];
        char *tp = tmp;
        int i;
        unsigned v;
        int sign;
        char *sp;


        sign = (radix == 10 && value < 0);
        if (sign)
                v = -value;
        else
                v = (unsigned)value;
        while (v || tp == tmp)
        {
                i = v % radix;
                v = v / radix;
                if (i < 10)
                        *tp++ = i+'0';
                else
                        *tp++ = i + 'a' - 10;
        }

        if (string == 0)
                string = (char *)malloc((tp-tmp)+sign+1);
        sp = string;

        if (sign)
                *sp++ = '-';
        while (tp > tmp)
                *sp++ = *--tp;
        *sp = 0;
        return string;
}



int bin2dec(char *bin)

{

        int b, k, m, n;

        int len, sum = 0;

        len = strlen(bin) - 1;

        for(k = 0; k <= len; k++)

        {

                n = (bin[k] - '0'); // char to numeric value

                if ((n > 1) || (n < 0))

                {

                        //puts("\n\n ERROR! BINARY has only 1 and 0!\n");

                        return (0);

                }

                for(b = 1, m = len; m > k; m--)

                {

                        // 1 2 4 8 16 32 64 ... place-values, reversed here

                        b *= 2;

                }

                // sum it up

                sum = sum + n * b;

                //printf("%d*%d + ",n,b); // uncomment to show the way this works

        }

        return(sum);

}


char* createDataChar2()
                {
        static char buffer[9]={0};
        int i = 0;
        for(i=0;i<=7;i++){
                buffer[i]=0;
        }
        buffer[8] ='\0';
        if (gpio_get_pin_value(DATA1))
        {
                buffer[7] = '0';
        }

        else if (!gpio_get_pin_value(DATA1))
        {

                buffer[7] = '1';
        }

        if (gpio_get_pin_value(DATA2))
        {
                buffer[6] = '0';
        }
        else if (!gpio_get_pin_value(DATA2))
        {

                buffer[6] = '1';
        }

        if (gpio_get_pin_value(DATA3))
        {
                buffer[5] = '0';
        }
        else if (!gpio_get_pin_value(DATA3))
        {

                buffer[5] = '1';
        }

        if (gpio_get_pin_value(DATA4))
        {
                buffer[4] = '0';
        }
        else if (!gpio_get_pin_value(DATA4))
        {
                buffer[4] = '1';
        }

        if (gpio_get_pin_value(DATA5))
        {
                buffer[3] = '0';
        }
        else if (!gpio_get_pin_value(DATA5))
        {

                buffer[3] = '1';
        }

        if (gpio_get_pin_value(DATA6))
        {
                buffer[2] = '0';
        }
        else if (!gpio_get_pin_value(DATA6))
        {
                buffer[2] = '1';
        }

        if (gpio_get_pin_value(DATA7))
        {
                buffer[1] = '0';
        }
        else if (!gpio_get_pin_value(DATA7))
        {

                buffer[1] = '1';
        }
        if (gpio_get_pin_value(DATA8))
        {
                buffer[0] = '0';
        }
        else if (!gpio_get_pin_value(DATA8))
        {

                buffer[0] = '1';
        }

        return buffer;
                }
void  RcvBinData2(){

        char buffer[18];
        char *data1;
        char *data2;
        char data_out[10];
        char *char_ret;
        char *num_ret;
        char data_num[10];
        int num_times_loop =0;
        gpio_clr_gpio_pin(NDAC);
        gpio_set_gpio_pin(ATN);

        int k=0;
        int s =0;
        int i;
        for(i=0;i<=16;i++){
                buffer[i]=0;
        }

        while(gpio_get_pin_value(EOI))
        {

                s++;
                gpio_set_gpio_pin(NRFD);



                while(gpio_get_pin_value(DAV)){


                }

                data1 =  createDataChar2();


                for (k =0; k<8;k++ )
                {
                        //uart_usb_putchar(data1[k]);
                        buffer[k+8]= data1[k];

                }

                //uart_usb_putchar(' ');

                // uart_usb_putchar(binaryToAscii( createDataChar()));
                //readDataPins();


                //uart_usb_flush();
                gpio_clr_gpio_pin(NRFD);  // Not ready for more data
                gpio_set_gpio_pin(NDAC);  // Data received



                while(! gpio_get_pin_value(DAV))
                {

                }
                gpio_clr_gpio_pin(NDAC);  // Data not accepted (no data on bus)




                // get the second byte


                gpio_set_gpio_pin(NRFD);



                while(gpio_get_pin_value(DAV)){


                }

                data2 =  createDataChar2();


                for (k =0; k<8;k++ )
                {
                        //uart_usb_putchar(data2[k]);
                        buffer[k]= data2[k];
                }


                //uart_usb_putchar(' ');

                /* for (k =0; k<16;k++ )
                    {
                          uart_usb_putchar(buffer[k]);
                     }*/


                gpio_clr_gpio_pin(NRFD);  // Not ready for more data
                gpio_set_gpio_pin(NDAC);  // Data received



                while(! gpio_get_pin_value(DAV))
                {

                }
                gpio_clr_gpio_pin(NDAC);  // Data not accepted (no data on bus)

                // strcpy(buffer,data2);
                //   strcat(buffer,data1);
                /*
       for (k =0; k<8;k++ )
       {
        buffer[k] = data2[k];
         }
       for (k =0; k<8;k++ )
        {
         buffer[k+8] = data1[k];
        }*/

                //   uart_usb_putchar(' ');
                //  uart_usb_putchar(' ');

                int ret = bin2dec(buffer);


                //ret = 1536;

                // uart_usb_putchar(' ');
                //        uart_usb_putchar(' ');

                char_ret = itoa(ret, data_out, 10);


                //num_ret = itoa(s, data_num, 10);

                /*for (k =0; k<strlen(num_ret);k++ )
                    {
                     uart_usb_putchar(num_ret[k]);
                   }*/
                //uart_usb_putchar(':');
                for (k =0; k<strlen(char_ret);k++ )
                {
                        uart_usb_putchar(char_ret[k]);
                        uart_usb_flush();
                }
                // uart_usb_putchar(' ');
                //  uart_usb_putchar(' ');

                uart_usb_putchar('\n');
        }
        uart_usb_flush();


        return ;

} // RcvBinData

void  RcvWaveformDump(){

    char buffer[18];
    char *data1;
    char *data2;
    char data_out[10];
    char *char_ret;
    char *num_ret;
    char data_num[10];
    int first_character =1;
    int second_character =0;
    int continuing = 1;
    int num_times;
    int mul = 10;

    gpio_clr_gpio_pin(NDAC);
    gpio_set_gpio_pin(ATN);

    int k=0;
    int s =0;
    int i;
    int ret;
    int counter =0;
     int num_times_loop = 0;
    for(i=0;i<=16;i++){
            buffer[i]=0;
    }


    int timeout =0;
    int timeout1 =0;
    while (timeout1 < 100)
    {
		while(gpio_get_pin_value(EOI) && continuing)
		{
			timeout1 = 200;

				gpio_set_gpio_pin(NRFD);



				while(gpio_get_pin_value(DAV)){


				}
				if(first_character)
				{

						data1 =  createDataChar2();
						ret = bin2dec(data1);
						char_ret = itoa(ret, data_out, 10);
						for (k =0; k<strlen(char_ret);k++ )
						{
						//uart_usb_putchar(char_ret[k]);
						}
						if (!(char_ret[0] =='3' && char_ret[1]=='5'))
						{
								uart_usb_putchar('N');
								uart_usb_putchar('O');
								uart_usb_putchar('T');
								uart_usb_putchar(' ');
								uart_usb_putchar('#');
								uart_usb_flush();

								return;
						}

								continuing = 1;
								first_character =0;
								second_character =1;

				}
				else if (second_character)
				{
						data1 =  createDataChar2();
						ret = bin2dec(data1);
						num_times = ret-48;
						char_ret = itoa(ret, data_out, 10);
						//uart_usb_putchar('T');
						//uart_usb_putchar('I');
						//uart_usb_putchar('M');
						//uart_usb_putchar('E');
						//uart_usb_putchar('S');

						//for (k =0; k<strlen(char_ret);k++ )
						//{
					   //         uart_usb_putchar(char_ret[k]);
					   // }
						//sendUSBString(char_ret);

						second_character =0;
				}
				else
				{
						counter++;
		 mul = mul/10;

						if (counter ==1)
						{
								ret =0;
								mul =1000;
						}
						data1 =  createDataChar2();
				ret += mul*(bin2dec(data1)-48);

				//uart_usb_putchar('O');
						if (counter == num_times)
						{
								ret = ret/2;

								//uart_usb_putchar('E');
														//uart_usb_putchar('N');
												//        uart_usb_putchar('D');

								continuing =0;
								char_ret = itoa(ret, data_out, 10);
								//for (k =0; k<strlen(char_ret);k++ )
							   ///// {
							   //         uart_usb_putchar(char_ret[k]);
							   // }
								//sendUSBString(char_ret);
						}

				}


				gpio_clr_gpio_pin(NRFD);  // Not ready for more data
				gpio_set_gpio_pin(NDAC);  // Data received



				while(! gpio_get_pin_value(DAV))
				{

				}
				gpio_clr_gpio_pin(NDAC);  // Data not accepted (no data on bus)

		}
		timeout ++;
    	if (timeout == 10)
		{
			timeout1++;
		}
	}


    //changed
    num_times_loop = ret;
    //while(gpio_get_pin_value(EOI))
    while (num_times_loop !=0)
    {

            num_times_loop --;

            gpio_set_gpio_pin(NRFD);



            while(gpio_get_pin_value(DAV)){


            }


            data1 =  createDataChar2();

            for (k =0; k<8;k++ )
            {
                    //uart_usb_putchar(data1[k]);
                    buffer[k+8]= data1[k];

            }

            //uart_usb_putchar(' ');

            // uart_usb_putchar(binaryToAscii( createDataChar()));
            //readDataPins();


            //uart_usb_flush();
            gpio_clr_gpio_pin(NRFD);  // Not ready for more data
            gpio_set_gpio_pin(NDAC);  // Data received



            while(! gpio_get_pin_value(DAV))
            {

            }
            gpio_clr_gpio_pin(NDAC);  // Data not accepted (no data on bus)





            // get the second byte


            gpio_set_gpio_pin(NRFD);



            while(gpio_get_pin_value(DAV)){


            }

            data2 =  createDataChar2();


            for (k =0; k<8;k++ )
            {

                    buffer[k]= data2[k];
            }





            gpio_clr_gpio_pin(NRFD);  // Not ready for more data
            gpio_set_gpio_pin(NDAC);  // Data received



            while(! gpio_get_pin_value(DAV))
            {

            }
            gpio_clr_gpio_pin(NDAC);  // Data not accepted (no data on bus)



            ret = bin2dec(buffer);



            char_ret = itoa(ret, data_out, 10);

            for (k =0; k<strlen(char_ret);k++ )
            {
                    uart_usb_putchar(char_ret[k]);
                    uart_usb_flush();
            }


            uart_usb_putchar('\n');
    }
uart_usb_flush();
    return ;

} // RcvBinData





void sendUSBString(char input[])
{
    int length = strlen(input);
    int i =0;

    for(i = 0; i < length; i++)
    {
        uart_usb_putchar(input[i]);
    }
    uart_usb_flush ();
}

//USB to SERIAL
void usb2ser()
{
	char c;
	//if (usart_tx_ready(DBG_USART)) // USART free ? ----
	 {
			//usart_putchar(DBG_USART,'\r');
			//usart_putchar(DBG_USART,'\n');
			int count = 0;
		while(1)
		{
			//while(!usart_tx_ready(DBG_USART)){} ----
			c= uart_usb_getchar();
			//if (c == '\n')
			//{
				//c ='\r';
			//}
			//uart_usb_putchar(c); ----
			//uart_usb_flush();
		//	count++; -------


			if( c=='^' )	//finish when receive carriage return
			{
				//sendUSBString("Serial Done");
				//usart_putchar(DBG_USART,'\r'); -------
				//usart_putchar(DBG_USART,'\n');
			  	return;
			}
			usart_putchar(DBG_USART,c);
		}
	 }
	//while(1){}
}

//USB to Parallel
void usb2par()
{
	char c;
	char strin[2];

	while(1)
	{
		c= uart_usb_getchar();
		if( c=='&' )	//finish when receive &
		{
			//sendUSBString("Parallel Done");
			return;
		}

		//send char on the bus
		setPinsDependingOnDataParallel(c);

		//wait if peripheral is busy
		while (gpio_get_pin_value(BUSY)) {}
		//strobe the nSTROBE line
		gpio_clr_gpio_pin(nSTROBE);
		gpio_set_gpio_pin(nSTROBE);
	}
}






char *chartobin ( unsigned char c )
{
    static char bin[CHAR_BIT + 1] = {0};
    int i;

    for ( i = CHAR_BIT - 1; i >= 0; i-- )
    {
        bin[i] = (c % 2) + '0';
        c /= 2;
    }
    return bin;
}

char binaryToAscii(int buffer[])
{
	char iVal={0};
	int i;
	for (i = 0 ; i < 7 ; i++ )
	{
		iVal = (iVal << 1) + (buffer[i] & 1);
	}
	return iVal;
}

void enablePins()
{
	gpio_enable_gpio_pin(SRQ);
		gpio_enable_gpio_pin(EOI);
		gpio_enable_gpio_pin(DAV);
		gpio_enable_gpio_pin(NRFD);
		gpio_enable_gpio_pin(NDAC);
		gpio_enable_gpio_pin(IFC);
		gpio_enable_gpio_pin(ATN);
		gpio_enable_gpio_pin(REN);

		gpio_enable_gpio_pin(TE);


		gpio_enable_gpio_pin(DATA1);
		gpio_enable_gpio_pin(DATA2);
		gpio_enable_gpio_pin(DATA3);
		gpio_enable_gpio_pin(DATA4);
		gpio_enable_gpio_pin(DATA5);
		gpio_enable_gpio_pin(DATA6);
		gpio_enable_gpio_pin(DATA7);
		gpio_enable_gpio_pin(DATA8);
		gpio_enable_gpio_pin(DC);
		gpio_clr_gpio_pin(DC);

}

int* createDataChar()
{
static int buffer[7]={0};
int i = 0;
for(i=0;i<=6;i++){
buffer[i]=0;
}
        if (gpio_get_pin_value(DATA1))
         {
                  buffer[6] = '0';
         }

         else if (!gpio_get_pin_value(DATA1))
         {

        	 buffer[6] = '1';
                 }

        if (gpio_get_pin_value(DATA2))
                 {
        	 buffer[5] = '0';
                 }
                 else if (!gpio_get_pin_value(DATA2))
                 {

                	 buffer[5] = '1';
                         }

        if (gpio_get_pin_value(DATA3))
                 {
        	 buffer[4] = '0';
                 }
                 else if (!gpio_get_pin_value(DATA3))
                 {

                	 buffer[4] = '1';
                         }

        if (gpio_get_pin_value(DATA4))
                 {
        	 buffer[3] = '0';
                 }
                 else if (!gpio_get_pin_value(DATA4))
                 {
                	 buffer[3] = '1';
                         }

        if (gpio_get_pin_value(DATA5))
                 {
        	 buffer[2] = '0';
                 }
                 else if (!gpio_get_pin_value(DATA5))
                 {

                	 buffer[2] = '1';
                         }

        if (gpio_get_pin_value(DATA6))
                 {
        	 buffer[1] = '0';
                 }
                 else if (!gpio_get_pin_value(DATA6))
                 {
                	 buffer[1] = '1';
                         }

        if (gpio_get_pin_value(DATA7))
                 {
        	 buffer[0] = '0';
                 }
                 else if (!gpio_get_pin_value(DATA7))
                 {

                	 buffer[0] = '1';
                         }

        return buffer;
}

void SetDataLines(char controls[])
{
        if(controls[7] == '0')
                gpio_clr_gpio_pin(DATA1);
        else if(controls[7] == '1')
                 gpio_set_gpio_pin(DATA1);

        if(controls[6] == '0')
                        gpio_clr_gpio_pin(DATA2);
        else if(controls[6] == '1')
                 gpio_set_gpio_pin(DATA2);

        if(controls[5] == '0')
                        gpio_clr_gpio_pin(DATA3);
        else if(controls[5] == '1')
                 gpio_set_gpio_pin(DATA3);

        if(controls[4] == '0')
                        gpio_clr_gpio_pin(DATA4);
        else if(controls[4] == '1')
                 gpio_set_gpio_pin(DATA4);

        if(controls[3] == '0')
                        gpio_clr_gpio_pin(DATA5);
        else if(controls[3] == '1')
                 gpio_set_gpio_pin(DATA5);

        if(controls[2] == '0')
                        gpio_clr_gpio_pin(DATA6);
        else if(controls[2] == '1')
                 gpio_set_gpio_pin(DATA6);

        if(controls[1] == '0')
                        gpio_clr_gpio_pin(DATA7);
        else if(controls[1] == '1')
                 gpio_set_gpio_pin(DATA7);

        if(controls[0] == '0')
                        gpio_clr_gpio_pin(DATA8);
        else if(controls[0] == '1')
                 gpio_set_gpio_pin(DATA8);
}

void SetControlLines(char controls[])
{
        if(controls[7] == '0')
                gpio_clr_gpio_pin(REN);
        else if(controls[7] == '1')
                 gpio_set_gpio_pin(REN);

        if(controls[6] == '0')
                        gpio_clr_gpio_pin(IFC);
        else if(controls[6] == '1')
                 gpio_set_gpio_pin(IFC);

        if(controls[5] == '0')
                        gpio_clr_gpio_pin(NDAC);
        else if(controls[5] == '1')
                 gpio_set_gpio_pin(NDAC);

        if(controls[4] == '0')
                        gpio_clr_gpio_pin(NRFD);
        else if(controls[4] == '1')
                 gpio_set_gpio_pin(NRFD);

        if(controls[3] == '0')
                        gpio_clr_gpio_pin(DAV);
        else if(controls[3] == '1')
                 gpio_set_gpio_pin(DAV);

        if(controls[2] == '0')
                        gpio_clr_gpio_pin(EOI);
        else if(controls[2] == '1')
                 gpio_set_gpio_pin(EOI);

        if(controls[1] == '0')
                        gpio_clr_gpio_pin(ATN);
        else if(controls[1] == '1')
                 gpio_set_gpio_pin(ATN);

        if(controls[0] == '0')
                        gpio_clr_gpio_pin(SRQ);
        else if(controls[0] == '1')
                 gpio_set_gpio_pin(SRQ);
}




void setPinsDependingOnData(char c)
{
	char *binary;
	binary = chartobin (  c );

	if (binary[7] == '1')
		gpio_clr_gpio_pin(DATA1);
	else if (binary[7] == '0')
		gpio_set_gpio_pin(DATA1);

	if (binary[6] == '1')
		gpio_clr_gpio_pin(DATA2);
	else if (binary[6] == '0')
		gpio_set_gpio_pin(DATA2);

	if (binary[5] == '1')
		gpio_clr_gpio_pin(DATA3);
	else if (binary[5] == '0')
		gpio_set_gpio_pin(DATA3);

	if (binary[4] == '1')
		gpio_clr_gpio_pin(DATA4);
	else if (binary[4] == '0')
		gpio_set_gpio_pin(DATA4);

	if (binary[3] == '1')
		gpio_clr_gpio_pin(DATA5);
	else if (binary[3] == '0')
		gpio_set_gpio_pin(DATA5);

	if (binary[2] == '1')
		gpio_clr_gpio_pin(DATA6);
	else if (binary[2] == '0')
		gpio_set_gpio_pin(DATA6);

	if (binary[1] == '1')
		gpio_clr_gpio_pin(DATA7);
	else if (binary[1] == '0')
		gpio_set_gpio_pin(DATA7);

	if (binary[0] == '1')
		gpio_clr_gpio_pin(DATA8);
	else if (binary[0] == '0')
		gpio_set_gpio_pin(DATA8);

	return;
}

void setPinsDependingOnDataParallel (char c)
{
	char *binary;
	binary = chartobin (  c );

	if (binary[7] == '0')
		gpio_clr_gpio_pin(DATA1_PA);
	else if (binary[7] == '1')
		gpio_set_gpio_pin(DATA1_PA);

	if (binary[6] == '0')
		gpio_clr_gpio_pin(DATA2_PA);
	else if (binary[6] == '1')
		gpio_set_gpio_pin(DATA2_PA);

	if (binary[5] == '0')
		gpio_clr_gpio_pin(DATA3_PA);
	else if (binary[5] == '1')
		gpio_set_gpio_pin(DATA3_PA);

	if (binary[4] == '0')
		gpio_clr_gpio_pin(DATA4_PA);
	else if (binary[4] == '1')
		gpio_set_gpio_pin(DATA4_PA);

	if (binary[3] == '0')
		gpio_clr_gpio_pin(DATA5_PA);
	else if (binary[3] == '1')
		gpio_set_gpio_pin(DATA5_PA);

	if (binary[2] == '0')
		gpio_clr_gpio_pin(DATA6_PA);
	else if (binary[2] == '1')
		gpio_set_gpio_pin(DATA6_PA);

	if (binary[1] == '0')
		gpio_clr_gpio_pin(DATA7_PA);
	else if (binary[1] == '1')
		gpio_set_gpio_pin(DATA7_PA);

	if (binary[0] == '0')
		gpio_clr_gpio_pin(DATA8_PA);
	else if (binary[0] == '1')
		gpio_set_gpio_pin(DATA8_PA);

	return;
}

void SetListenerTalker(char c)
{
	gpio_clr_gpio_pin(ATN);
	setPinsDependingOnData(c);
	while (gpio_get_pin_value(NDAC) && gpio_get_pin_value(NRFD)){
		//sendUSBString("in the loop1 set listener talker&");
	}
	while(!gpio_get_pin_value(NRFD)){
		//sendUSBString("in the loop2 set listener talker&");
	}
	gpio_clr_gpio_pin(DAV);
	while(!gpio_get_pin_value(NDAC)){
		//sendUSBString("in the loop3 set listener talker&");
	}
	gpio_set_gpio_pin(DAV);
}

void RcvBinData(){
char temp;
int timeout =0;
int timeout1 =0;
    gpio_clr_gpio_pin(NDAC);
    gpio_set_gpio_pin(ATN);

    while (timeout1 < 100)
        {
	while(gpio_get_pin_value(EOI))
	{

        gpio_set_gpio_pin(NRFD);

        while(gpio_get_pin_value(DAV)){}

        uart_usb_flush();
        temp = (binaryToAscii( createDataChar()));
        uart_usb_putchar(temp);
        uart_usb_flush();
        gpio_clr_gpio_pin(NRFD);  // Not ready for more data
        gpio_set_gpio_pin(NDAC);  // Data received

        while(! gpio_get_pin_value(DAV)){}
        gpio_clr_gpio_pin(NDAC);  // Data not accepted (no data on bus)

                timeout1 =200;
    }
	timeout ++;
	if (timeout == 10)
		{
			timeout1++;
		}
        }
    gpio_clr_gpio_pin(ATN);
    uart_usb_flush();

} // RcvBinData


void RcvBinDataChanged(){
char temp;
    gpio_clr_gpio_pin(NDAC);
    gpio_set_gpio_pin(ATN);

    int timeout =0;
    int timeout1 = 0;
    while (timeout1 < 10)
    {

	while(gpio_get_pin_value(EOI))
	{

        gpio_set_gpio_pin(NRFD);

        while(gpio_get_pin_value(DAV)){}

        uart_usb_flush();
        temp = (binaryToAscii( createDataChar()));
        uart_usb_putchar(temp);
        uart_usb_flush();
        gpio_clr_gpio_pin(NRFD);  // Not ready for more data
        gpio_set_gpio_pin(NDAC);  // Data received

        while(! gpio_get_pin_value(DAV)){}
        gpio_clr_gpio_pin(NDAC);  // Data not accepted (no data on bus)
        timeout =0;
        timeout1 =10;
    }
	timeout ++;
	if (timeout == 10)
	{
		timeout1++;
	}
    }

    gpio_clr_gpio_pin(ATN);
    uart_usb_flush();

} // RcvBinData


void init_GPIB()
{
	enablePins();

	//set pin directions
	 gpio_enable_pin_open_drain(SRQ);
	 gpio_enable_pin_open_drain(NRFD);
	 gpio_enable_pin_open_drain(NDAC);
	 gpio_clr_gpio_pin(REN);
	 gpio_clr_gpio_pin(ATN);
	 gpio_set_gpio_pin(DAV);
	 gpio_set_gpio_pin(EOI);
	 gpio_set_gpio_pin(IFC);
	 gpio_set_gpio_pin(TE);
	 //gpio_clr_gpio_pin(DC);

}

int getPcInt()
{
	char string[10]="\0";
	int value;
	int i=0;

	//read until a space character
	char c= uart_usb_getchar();
	while(c!=' ')
	{
		string[i] = c;
		i++;
		c= uart_usb_getchar();
	}
	string[i] = '\0';

	//parse int and return
	sscanf(string, "%d", &value);
	return value;
}

int sendGPIBData()
{

	//prepare pins for write
	gpio_enable_gpio_pin(NRFD);
	gpio_enable_gpio_pin(EOI);
	gpio_enable_gpio_pin(NDAC);
	gpio_enable_gpio_pin(DAV);
	gpio_enable_gpio_pin(ATN);
	gpio_enable_pin_open_drain(SRQ);
	gpio_enable_pin_open_drain(NRFD);
	gpio_enable_pin_open_drain(NDAC);
	gpio_clr_gpio_pin(REN);
	gpio_clr_gpio_pin(ATN);
	gpio_set_gpio_pin(DAV);
	gpio_set_gpio_pin(EOI);
	gpio_set_gpio_pin(IFC);
	gpio_set_gpio_pin(TE);
	//gpio_clr_gpio_pin(DC);

	//expects PC to send numAddresses, space, 2 char addresses (no spaces), dataLength, space, data
	int numAddresses, dataLength, i, address;
	char c;

//TODO: for setlistenertalker and the send data code, put limits on while loop and return error code int
	numAddresses = getPcInt();

	SetListenerTalker('_');	  //Untalk

	SetListenerTalker('?');	  //Unlisten

	SetListenerTalker('@');  // for talker :(hex) 40 + address of controller) in this case (hex)40 + 0 is @ in ascii

	for(i=0; i<numAddresses*2; i=i+2)
	{
		address = (uart_usb_getchar() -48)*10 +  (uart_usb_getchar() -48);	//convert two ascii chars to a two digit integer address
		SetListenerTalker(32+address); //for listener :(hex) 20 + address of the instrument)
	}

	//send data
	dataLength = getPcInt();
	for(i=0; i<dataLength-1; i++)
	{
		//sendUSBString("ent");
		c= uart_usb_getchar();
		uart_usb_putchar(c);
		uart_usb_flush();
		//sendUSBString("sending");
		gpio_set_gpio_pin(ATN);
		setPinsDependingOnData(c);
		while (gpio_get_pin_value(NDAC) && gpio_get_pin_value(NRFD)){
			//sendUSBString("in the loop1 send command");
		}
		while(!gpio_get_pin_value(NRFD)){
			//sendUSBString("in the loop2 send command");
		}
		gpio_clr_gpio_pin(DAV);
		while(!gpio_get_pin_value(NDAC)){
			//sendUSBString("in the loop3 send command");
		}
		gpio_set_gpio_pin(DAV);
	}
	gpio_clr_gpio_pin(EOI);
	c= uart_usb_getchar();
	uart_usb_putchar(c);
	uart_usb_flush();
	setPinsDependingOnData(c);
	while (gpio_get_pin_value(NDAC) && gpio_get_pin_value(NRFD)){	}
	while(!gpio_get_pin_value(NRFD)){	}
	gpio_clr_gpio_pin(DAV);
	while(!gpio_get_pin_value(NDAC)){	}
	gpio_set_gpio_pin(DAV);
	gpio_set_gpio_pin(EOI);
	return 0;
}

int readGPIB()
{
	//expects PC to send a two char address followed by space
	int address;
	resetBus();
//TODO: for setlistenertalker, put limits on while loop and return error code int
	SetListenerTalker('?');  //Unlisten
	SetListenerTalker(' '); // (for listener: (hex) 20 + address of controller) in this case 20+0
	address = (uart_usb_getchar() -48)*10 +  (uart_usb_getchar() -48);
	SetListenerTalker(64+address); //(for talker:(hex) 40 + address of the instrument) or decimal 64+address

	gpio_clr_gpio_pin(TE);
	//setup pins for reading
	gpio_enable_gpio_pin(NRFD);
	gpio_enable_gpio_pin(NDAC);
	gpio_enable_pin_open_drain(DAV);
	gpio_enable_pin_open_drain(EOI);
	gpio_enable_gpio_pin(DATA1);
	gpio_enable_gpio_pin(DATA2);
	gpio_enable_gpio_pin(DATA3);
	gpio_enable_gpio_pin(DATA4);
	gpio_enable_gpio_pin(DATA5);
	gpio_enable_gpio_pin(DATA6);
	gpio_enable_gpio_pin(DATA7);
	gpio_enable_gpio_pin(DATA8);

	RcvBinData();

	resetBus();
	return 0;
}

int readGPIBWF()
{
	//expects PC to send a two char address followed by space
		int address;
		resetBus();
	//TODO: for setlistenertalker, put limits on while loop and return error code int
		SetListenerTalker('?');  //Unlisten
		SetListenerTalker(' '); // (for listener: (hex) 20 + address of controller) in this case 20+0
		address = (uart_usb_getchar() -48)*10 +  (uart_usb_getchar() -48);
		SetListenerTalker(64+address); //(for talker:(hex) 40 + address of the instrument) or decimal 64+address
		gpio_clr_gpio_pin(TE);
		//setup pins for reading
		gpio_enable_gpio_pin(NRFD);
		gpio_enable_gpio_pin(NDAC);
		gpio_enable_pin_open_drain(DAV);
		gpio_enable_pin_open_drain(EOI);
		gpio_enable_gpio_pin(DATA1);
		gpio_enable_gpio_pin(DATA2);
		gpio_enable_gpio_pin(DATA3);
		gpio_enable_gpio_pin(DATA4);
		gpio_enable_gpio_pin(DATA5);
		gpio_enable_gpio_pin(DATA6);
		gpio_enable_gpio_pin(DATA7);
		gpio_enable_gpio_pin(DATA8);

	RcvWaveformDump();
	resetBus();
	return 0;
}

char binaryToAsciiPar(int buffer[])
{

	char iVal={0};
	int i;
	for (i = 0 ; i < 8 ; i++ )
	{

	iVal = (iVal << 1) + (buffer[i] & 1);
	}

	return iVal;


}

int* createDataCharParallel()
{
static int buffer[8]={0};
int i = 0;
for(i=0;i<=7;i++){
buffer[i]=0;
}
        if (gpio_get_pin_value(DATA1_PA))
        {
                 buffer[7] = '1';
        }

        else if (!gpio_get_pin_value(DATA1_PA))
        {

            buffer[7] = '0';
                }

        if (gpio_get_pin_value(DATA2_PA))
         {
                  buffer[6] = '1';
         }

         else if (!gpio_get_pin_value(DATA2_PA))
         {

             buffer[6] = '0';
                 }

        if (gpio_get_pin_value(DATA3_PA))
                 {
             buffer[5] = '1';
                 }
                 else if (!gpio_get_pin_value(DATA3_PA))
                 {

                     buffer[5] = '0';
                         }

        if (gpio_get_pin_value(DATA4_PA))
                 {
             buffer[4] = '1';
                 }
                 else if (!gpio_get_pin_value(DATA4_PA))
                 {

                     buffer[4] = '0';
                         }

        if (gpio_get_pin_value(DATA5_PA))
                 {
             buffer[3] = '1';
                 }
                 else if (!gpio_get_pin_value(DATA5_PA))
                 {
                     buffer[3] = '0';
                         }

        if (gpio_get_pin_value(DATA6_PA))
                 {
             buffer[2] = '1';
                 }
                 else if (!gpio_get_pin_value(DATA6_PA))
                 {

                     buffer[2] = '0';
                         }

        if (gpio_get_pin_value(DATA7_PA))
                 {
             buffer[1] = '1';
                 }
                 else if (!gpio_get_pin_value(DATA7_PA))
                 {
                     buffer[1] = '0';
                         }

        if (gpio_get_pin_value(DATA8_PA))
                 {
             buffer[0] = '1';
                 }
                 else if (!gpio_get_pin_value(DATA8_PA))
                 {

                     buffer[0] = '0';
                         }

        return buffer;
}


void enableParallelPins()
{
        gpio_enable_gpio_pin(nSTROBE);
        gpio_enable_gpio_pin(nACK);
        gpio_enable_gpio_pin(BUSY);
        gpio_enable_gpio_pin(PAPEREND);
        gpio_enable_gpio_pin(SELECT);
        gpio_enable_gpio_pin(nAUTOLF);
        gpio_enable_gpio_pin(nERROR);
        gpio_enable_gpio_pin(nINIT);
        gpio_enable_gpio_pin(nSELECTIN);


        gpio_enable_gpio_pin(DATA1_PA);
        gpio_enable_gpio_pin(DATA2_PA);
        gpio_enable_gpio_pin(DATA3_PA);
        gpio_enable_gpio_pin(DATA4_PA);
        gpio_enable_gpio_pin(DATA5_PA);
        gpio_enable_gpio_pin(DATA6_PA);
        gpio_enable_gpio_pin(DATA7_PA);
        gpio_enable_gpio_pin(DATA8_PA);
}


void setupParallelRead()
{
	enableParallelPins();

	gpio_enable_pin_open_drain(nSTROBE);
	gpio_enable_pin_open_drain(DATA1_PA);
	gpio_enable_pin_open_drain(DATA2_PA);
	gpio_enable_pin_open_drain(DATA3_PA);
	gpio_enable_pin_open_drain(DATA4_PA);
	gpio_enable_pin_open_drain(DATA5_PA);
	gpio_enable_pin_open_drain(DATA6_PA);
	gpio_enable_pin_open_drain(DATA7_PA);
	gpio_enable_pin_open_drain(DATA8_PA);
	gpio_set_gpio_pin(BUSY);
	gpio_set_gpio_pin(nACK);
	gpio_set_gpio_pin(SELECT);
	gpio_clr_gpio_pin(PAPEREND);
}

void setupParallelWrite()
{
	enableParallelPins();

	gpio_enable_pin_open_drain(BUSY);
	gpio_enable_pin_open_drain(nACK);
	gpio_enable_pin_open_drain(SELECT);
	gpio_enable_pin_open_drain(PAPEREND);
}

